/**
 * 
 */
package com.gragra.sampling.nonproj;
import com.gragra.sampling.binary.HeadAssignmentStructure;
import com.gragra.sampling.nonproj.structures.nonprojective.NonProjDepdTree;
import com.gragra.sampling.sequentialStructure.ExtensionLevels;
import com.gragra.sampling.sequentialStructure.WordType;
import it.unimi.dsi.fastutil.ints.IntSet;
/**
 * @author Christoph Teichmann
 * 19.10.2013
 */
public class DistHeadConstraint extends DistHeadModel
{
	/**
	 * 
	 */
	private final double nounConstraint;
	/**
	 * 
	 */
	private final double functionConstraint;
	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private final double adjectiveConstraint;
	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private final double determinerConstraint;
	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private final double verbConstraint;
	/**
	 * @param population
	 * @param tags
	 * @param tagTagAlpha
	 * @param tagDistAlpha
	 * @param fertAlpha
	 * @param nounConstraint
	 * @param functionConstraint
	 * @param adjectiveConstraint
	 * @param determinerConstraint
	 * @param verbConstraint
	 */
	public DistHeadConstraint(int population, IntSet tags, double tagTagAlpha,
			double tagDistAlpha, double fertAlpha, double nounConstraint,
			double functionConstraint, double adjectiveConstraint,
			double determinerConstraint, double verbConstraint)
	{
		super(population, tags, tagTagAlpha, tagDistAlpha, fertAlpha);
		this.nounConstraint = -nounConstraint;
		this.functionConstraint = -functionConstraint;
		this.adjectiveConstraint = -adjectiveConstraint;
		this.determinerConstraint = -determinerConstraint;
		this.verbConstraint = -verbConstraint;
	}
	/* (non-Javadoc)
	 * @see com.gragra.sampling.nonproj.DistHeadModel#makeDistanceAndOtherConstraints(int, com.gragra.sampling.binary.HeadAssignmentStructure, int)
	 */
	@Override
	protected double makeDistanceAndOtherConstraints(int pos,
			HeadAssignmentStructure has, int thread)
	{
		double val = 0.0;
		NonProjDepdTree tree = (NonProjDepdTree) has;
		WordType wt = (WordType) tree.getExtensionInformation().getFiniteInformation(pos, ExtensionLevels.WordTypeLevel);
		int head;
		if(wt != null)
		{
			switch(wt)
			{
			/*
			case Verb:
				if(tree.numberOfChildren(pos, thread) < 1)
				{val = this.verbConstraint;}
				break;
			case Adjective:
				head = tree.getHeadPosition(pos, thread);
				hW = head == tree.getDependencyRootPosition() || head == -1 ? 
						null : (WordType) tree.getExtensionInformation().getFiniteInformation(head, ExtensionLevels.WordTypeLevel);
				if(!(hW == WordType.Verb || hW == WordType.Noun))
				{val = this.adjectiveConstraint;}
				break;
			*/
			case Noun:
				head = tree.getHeadPosition(pos, thread);
				if(head == tree.getDependencyRootPosition())
				{val = this.nounConstraint;}
				break;
			case Function:
				head = tree.getHeadPosition(pos, thread);
				if(head == tree.getDependencyRootPosition())
				{val = this.functionConstraint;}
				break;
			case Determiner:
				head = tree.getHeadPosition(pos, thread);
				if(head == tree.getDependencyRootPosition())
				{val = this.functionConstraint;}
				break;
			/*
			case Determiner:
				head = tree.getHeadPosition(pos, thread);
				hW = head == tree.getDependencyRootPosition() || head == -1 ? 
						null : (WordType) tree.getExtensionInformation().getFiniteInformation(head, ExtensionLevels.WordTypeLevel);
				if(hW != WordType.Noun)
				{
					boolean nounChild = false;
					BitSet bs = tree.getDaughters(pos, thread);
					for(int p=bs.nextSetBit(0);p>=0;p=bs.nextSetBit(p+1))
					{
						if(tree.getExtensionInformation().getFiniteInformation(p, ExtensionLevels.WordTypeLevel) == WordType.Noun)
						{
							nounChild = true;
							break;
						}
					}
					if(!nounChild)
					{val = this.determinerConstraint;}
				}
				break;
			*/
			case Other:
				break;
			default:
				break;
			}
		}
		return super.makeDistanceAndOtherConstraints(pos, has, thread)+val;
	}
}